#include <stdio.h>
#include <stdbool.h>

#define MaxSize 10 // 队列的最大容量

typedef struct
{
    int data[MaxSize]; // 静态数组存储队列元素
    int front;         // 队头指针
    int rear;          // 队尾指针
} SqQueue;

// 1. 初始化队列
void InitQueue(SqQueue &Q)
{
    Q.front = Q.rear = 0; // 队头和队尾指针都指向0
}

// 2. 销毁队列（顺序队列无需特殊操作）
void DestroyQueue(SqQueue &Q)
{
    Q.front = Q.rear = 0; // 重置指针即可
}

// 3. 入队操作
bool EnQueue(SqQueue &Q, int x)
{
    if ((Q.rear + 1) % MaxSize == Q.front)
    { // 队满判断
        printf("Queue is full!\n");
        return false;
    }
    Q.data[Q.rear] = x;              // 存入队尾
    Q.rear = (Q.rear + 1) % MaxSize; // 队尾指针循环后移
    return true;
}

// 4. 出队操作
bool DeQueue(SqQueue &Q, int &x)
{
    if (Q.front == Q.rear)
    { // 队空判断
        printf("Queue is empty!\n");
        return false;
    }
    x = Q.data[Q.front];               // 获取队头元素
    Q.front = (Q.front + 1) % MaxSize; // 队头指针循环后移
    return true;
}

// 5. 获取队头元素
bool GetHead(SqQueue Q, int &x)
{
    if (Q.front == Q.rear)
    { // 队空判断
        printf("Queue is empty!\n");
        return false;
    }
    x = Q.data[Q.front];
    return true;
}

// 6. 获取队尾元素
bool GetTail(SqQueue Q, int &x)
{
    if (Q.front == Q.rear)
    { // 队空判断
        printf("Queue is empty!\n");
        return false;
    }
    int tailPos = (Q.rear - 1 + MaxSize) % MaxSize; // 计算队尾位置
    x = Q.data[tailPos];
    return true;
}

// 7. 判空操作
bool IsEmpty(SqQueue Q)
{
    return (Q.front == Q.rear);
}

// 8. 判满操作
bool IsFull(SqQueue Q)
{
    return ((Q.rear + 1) % MaxSize == Q.front);
}

// 打印队列内容（从队头到队尾）
void PrintQueue(SqQueue Q)
{
    if (IsEmpty(Q))
    {
        printf("Queue is empty\n");
        return;
    }

    printf("Queue [front->rear]: ");
    int i = Q.front;
    while (i != Q.rear)
    {
        printf("%d ", Q.data[i]);
        i = (i + 1) % MaxSize;
    }
    printf("\n");
}

int main()
{
    SqQueue Q;
    InitQueue(Q); // 初始化队列

    // 入队操作
    EnQueue(Q, 10);
    EnQueue(Q, 20);
    EnQueue(Q, 30);
    PrintQueue(Q); // Queue [front->rear]: 10 20 30

    // 获取队头和队尾
    int head, tail;
    GetHead(Q, head);
    GetTail(Q, tail);
    printf("Head: %d, Tail: %d\n", head, tail); // Head: 10, Tail: 30

    // 出队操作
    int dequeued;
    DeQueue(Q, dequeued);
    printf("Dequeued: %d\n", dequeued); // Dequeued: 10
    PrintQueue(Q);                      // Queue [front->rear]: 20 30

    // 判空和判满测试
    printf("Is empty? %s\n", IsEmpty(Q) ? "true" : "false");
    printf("Is full? %s\n", IsFull(Q) ? "true" : "false");

    // 队列满测试
    printf("Testing queue full:\n");
    for (int i = 0; i < MaxSize + 2; i++)
    {
        if (!EnQueue(Q, i))
            break;
    }

    // 队列空测试
    printf("Testing queue empty:\n");
    while (DeQueue(Q, dequeued))
    {
        printf("Dequeued: %d\n", dequeued);
    }

    DestroyQueue(Q); // 销毁队列
    return 0;
}